package com.llb666.shop.items.api.controller;

import com.llb666.common.core.constant.AppConstants;
import com.llb666.common.core.enums.CommentLevel;
import com.llb666.common.core.utils.page.PagedGridResult;
import com.llb666.common.core.web.response.BaseResponse;
import com.llb666.common.core.web.response.DataResponse;
import com.llb666.shop.cart.api.vo.ShopCartVo;
import com.llb666.shop.items.api.dto.OrderItemsDto;
import com.llb666.shop.items.api.vo.CommentLevelCountsVo;
import com.llb666.shop.items.api.vo.ItemsInfoVo;
import com.llb666.shop.items.api.vo.SearchItemsVo;
import com.llb666.shop.items.domain.entity.Items;
import com.llb666.shop.items.domain.entity.ItemsImg;
import com.llb666.shop.items.domain.entity.ItemsParam;
import com.llb666.shop.items.domain.entity.ItemsSpec;
import com.llb666.shop.items.domain.entity.bo.ItemsCommentBo;
import com.llb666.shop.items.domain.entity.bo.OrderItemsBo;
import com.llb666.shop.items.domain.service.ItemsEsService;
import com.llb666.shop.items.domain.service.ItemsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 商品用户展示层.
 *
 * @author llb666
 */
@RestController
@Tag(name = "商品信息展示的相关接口")
@RequestMapping("/items")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ItemsController {

    private final ItemsService itemsService;
    private final ItemsEsService itemsESService;


    @Operation(summary = "查询商品详情信息")
    @GetMapping("/info/{itemId}")
    public BaseResponse queryById(@Parameter(name = "itemId", description = "商品iD", required = true)
                                  @PathVariable String itemId) {
        if (StringUtils.isBlank(itemId)) {
            return DataResponse.errorMap("商品id不能为空");
        }
        // 商品基础信息.
        CompletableFuture<Items> itemsFuture = itemsService.queryById(itemId);
        // 商品图片信息.
        CompletableFuture<List<ItemsImg>> itemsImgsFuture = itemsService.queryItemsImgById(itemId);
        // 商品规则信息.
        CompletableFuture<List<ItemsSpec>> itemsSpecsFuture = itemsService.queryItemsSpecById(itemId);
        // 商品参数信息.
        CompletableFuture<ItemsParam> itemsParamFuture = itemsService.queryItemsParamById(itemId);
        CompletableFuture.allOf(itemsFuture, itemsImgsFuture, itemsSpecsFuture, itemsParamFuture);
        Items items = itemsFuture.join();
        List<ItemsImg> itemsImgs = itemsImgsFuture.join();
        List<ItemsSpec> itemsSpecs = itemsSpecsFuture.join();
        ItemsParam itemsParam = itemsParamFuture.join();
        ItemsInfoVo itemInfoVO = ItemsInfoVo.convert(items, itemsImgs, itemsSpecs, itemsParam);
        return DataResponse.ok(itemInfoVO);
    }

    @Operation(summary = "查询商品评论等级")
    @GetMapping("/commentLevel")
    public BaseResponse queryCommentLevel(@Parameter(name = "itemId", description = "商品iD", required = true)
                                          @RequestParam String id) {
        if (StringUtils.isBlank(id)) {
            return DataResponse.errorMap("商品id不能为空");
        }
        // 好评数量.
        Integer goodCommentCounts = itemsService.getCommentCount(id, CommentLevel.GOOD.type);
        // 中评数量.
        Integer normalCommentCounts = itemsService.getCommentCount(id, CommentLevel.NORMAL.type);
        // 差评数量.
        Integer badCommentCounts = itemsService.getCommentCount(id, CommentLevel.BAD.type);

        Integer totalCommentCounts = goodCommentCounts + normalCommentCounts + badCommentCounts;
        CommentLevelCountsVo countsVo = new CommentLevelCountsVo(totalCommentCounts,goodCommentCounts,
                normalCommentCounts,badCommentCounts);
        return DataResponse.ok(countsVo);
    }

    @Operation(summary = "查询商品评论列表")
    @GetMapping("/comments")
    public BaseResponse queryComments(@Parameter(name = "itemId", description = "商品iD", required = true) @RequestParam String itemsId,
                                          @Parameter(name = "level", description = "评论等级") @RequestParam Integer level,
                                          @Parameter(name = "page", description = "页数")  Integer page,
                                          @Parameter(name = "pageSize", description = "每页显示条数")  Integer pageSize) {
        if (StringUtils.isBlank(itemsId)) {
            return DataResponse.errorMap("商品id不能为空");
        }
        if (page == null) {
            page = AppConstants.COMMON_PAGE;
        }
        if (pageSize == null) {
            pageSize = AppConstants.COMMON_PAGE_SIZE;
        }
        PagedGridResult<ItemsCommentBo> pagedGridResult = itemsService.queryItemCommentByPage(itemsId, level, page, pageSize);
        return DataResponse.ok(pagedGridResult);
    }

    /**
     * 结合elasticsearch 查询数据
     */
    @Operation(summary = "搜索商品列表")
    @GetMapping("/search")
    public BaseResponse search(
            @Parameter(name = "keywords", description = "关键字", required = true) @RequestParam String keywords,
            @Parameter(name = "sort", description = "排序") @RequestParam String sort,
            @Parameter(name = "page", description = "查询下一页的第几页") @RequestParam Integer page,
            @Parameter(name = "pageSize", description = "分页的每一页显示的条数") @RequestParam Integer pageSize) {
        if (StringUtils.isBlank(keywords)) {
            return DataResponse.errorMsg(null);
        }
        if (page == null) {
            page = AppConstants.COMMON_PAGE;
        }
        if (pageSize == null) {
            pageSize = AppConstants.COMMON_PAGE_SIZE;
        }
        // 根据keywords, sort, page, pageSize 去elasticsearch查询数据返回商品id列表.
        page--;
        //es高亮查询.
        PagedGridResult<SearchItemsVo> grid = itemsESService.highlightSearchItems(keywords, sort, page, pageSize);
        return DataResponse.ok(grid);
    }

    @Operation(summary = "通过分类id搜索商品列表")
    @GetMapping("/catItems")
    public BaseResponse catItems(
            @Parameter(name = "catId", description = "三级分类id", required = true) @RequestParam Integer catId,
            @Parameter(name = "sort", description = "排序") @RequestParam String sort,
            @Parameter(name = "page", description = "查询下一页的第几页") Integer page,
            @Parameter(name = "pageSize", description = "分页的每一页显示的条数") Integer pageSize) {
        if (catId == null) {
            return DataResponse.errorMsg(null);
        }
        if (page == null) {
            page = AppConstants.COMMON_PAGE;
        }
        if (pageSize == null) {
            pageSize = AppConstants.COMMON_PAGE_SIZE;
        }
        PagedGridResult<SearchItemsVo> grid = itemsService.searchItems(catId, sort, page, pageSize);
        return DataResponse.ok(grid);
    }

    /**
     * 用于用户长时间未登录网站，刷新购物车中的数据（主要是商品价格），类似京东淘宝
     *
     * @param itemSpecIds 拼接的规格ids
     * @return JSONResult
     */
    @Operation(summary = "刷新购物车中的数据（主要是商品价格）")
    @GetMapping("/refresh")
    public BaseResponse refresh(
            @Parameter(name = "itemSpecIds", description = "拼接的规格ids", required = true, example = "1001,1003,1005")
            @RequestParam String itemSpecIds) {
        if (StringUtils.isBlank(itemSpecIds)) {
            return BaseResponse.ok();
        }
        List<ShopCartVo> list = ShopCartVo.Converter.INSTANCE.bo2VoList(itemsService.queryItemsBySpecIds(itemSpecIds));
        return DataResponse.ok(list);
    }

    /**************************************  feign 提供对外服务接口  ***********************************/

    @Operation(summary = "减库存")
    @PostMapping("/decreaseStock")
    public void decreaseItemSpecStock(@RequestParam("itemSpecId") String itemSpecId,
                                      @RequestParam("buyCounts") int buyCounts) {
        itemsService.decreaseItemSpecStock(itemSpecId, buyCounts);
    }

    @Operation(summary = "查询下单需要的商品信息")
    @PostMapping("/orderItems")
    OrderItemsBo getOrderItemsBo(@RequestBody OrderItemsDto orderItemsDto) {
        List<String> itemIds = orderItemsDto.getItemIds();
        List<String> itemSpecIdList = orderItemsDto.getItemSpecIdList();
        return itemsService.getOrderItemsBo(itemIds, itemSpecIdList);
    }
}
